package org.budo.netty.servlet.server.session;

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;

import org.budo.netty.servlet.server.event.EventBus;
import org.budo.netty.servlet.server.handler.servlet.BudoServletContext;
import org.budo.netty.servlet.server.session.repository.SessionRepository;

/**
 * @author lmw
 */
public class BudoHttpSession extends AbstractBudoHttpSession {
    private String id;

    private ServletContext servletContext;

    private Map<String, Object> attributeMap = new HashMap<String, Object>();

    private boolean isNew = false;

    private long creationTime;

    public BudoHttpSession(String sessionId, ServletContext servletContext) {
        this.id = sessionId;
        this.servletContext = servletContext;

        this.creationTime = System.currentTimeMillis();
    }

    @Override
    public long getCreationTime() {
        return this.creationTime;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void setAttribute(String name, Object value) {
        EventBus eventBus = ((BudoServletContext) this.getServletContext()).getBudoServletServer().getEventBus();
        eventBus.sessionAttributeSetted(this, name, value);

        this.attributeMap.put(name, value);
    }

    @Override
    public void removeAttribute(String name) {
        EventBus eventBus = ((BudoServletContext) this.getServletContext()).getBudoServletServer().getEventBus();
        eventBus.sessionAttributeRemoved(this, name);

        this.attributeMap.remove(name);
    }

    @Override
    public Object getAttribute(String name) {
        return this.attributeMap.get(name);
    }

    @Override
    public Enumeration<String> getAttributeNames() {
        return Collections.enumeration(this.attributeMap.keySet());
    }

    @Override
    public String[] getValueNames() {
        Set<String> keys = this.attributeMap.keySet();
        return keys.toArray(new String[keys.size()]);
    }

    @Override
    public ServletContext getServletContext() {
        return this.servletContext;
    }

    @Override
    public void invalidate() {
        EventBus eventBus = ((BudoServletContext) this.getServletContext()).getBudoServletServer().getEventBus();
        SessionRepository sessionRepository = ((BudoServletContext) this.getServletContext()).getBudoServletServer().getSessionRepository();

        eventBus.sessionDestroyed(this);
        sessionRepository.deleteById(this.getId());
    }

    @Override
    public boolean isNew() {
        return this.isNew;
    }

    public void setIsNew(boolean isNew) {
        this.isNew = isNew;
    }

    @Override
    public String toString() {
        return super.toString() + ", id=" + this.getId() + ", isNew=" + this.isNew();
    }
}